home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / COMMS / C011.ZIP / CRC.C < prev    next >
Text File  |  1990-01-19  |  6KB  |  143 lines

  1. /********************************************************************
  2.  * C Users Group (U.K) C Source Code Library File CUGLIB.011        *
  3.  * Inquiries to: M. Houston, 36 Whetstone Clo. Farquhar Rd.         *
  4.  * Edgbaston, Birmingham B15 2QN ENGLAND                *
  5.  ********************************************************************
  6.  * File name: crc.c
  7.  * Program name: library module
  8.  * Source of file:
  9.  * Purpose: CRC calculations
  10.  * Changes: <who what when & why major changes have been made>      
  11.  ********************************************************************/
  12.  
  13. /******************************************************************************
  14. *                                                                             *
  15. *               Cyclic Redundancy Check (CRC) functions                       *
  16. *                                                                             *
  17. ******************************************************************************/
  18.  
  19. /*
  20. *   crc_clear:
  21. *    This function clears the CRC to zero. It should be called prior to
  22. *    the start of the processing of a block for both received messages,
  23. *    and messages to be transmitted.
  24. *
  25. *    Calling sequence:
  26. *
  27. *    short crc;
  28. *    crc = crc_clear();
  29. */
  30. short crc_clear()
  31. {
  32.     return(0);
  33. }
  34. /*
  35. *   crc_update:
  36. *    this function must be called once for each character which is
  37. *    to be included in the CRC for messages to be transmitted.
  38. *    This function is called once for each character which is included
  39. *    in the CRC of a received message, AND once for each of the two CRC
  40. *    characters at the end of the received message. If the resulting
  41. *    CRC is zero, then the message has been correctly received.
  42. *
  43. *   Calling sequence:
  44. *
  45. *    crc = crc_update(crc,next_char);
  46. */
  47. short crc_update(crc,crc_char)
  48. short crc;
  49. char crc_char;
  50. {
  51.     long x;
  52.     short i;
  53.  
  54. /* "x" will contain the character to be processed in bits 0-7 and the CRC    */
  55. /* in bits 8-23. Bit 24 will be used to test for overflow, and then cleared  */
  56. /* to prevent the sign bit of "x" from being set to 1. Bits 25-31 are not    */
  57. /* used. ("x" is treated as though it is a 32 bit register).                 */
  58.     x = ((long)crc << 8) + crc_char;    /* Get the CRC and the character */
  59.  
  60. /* Repeat the following loop 8 times (for the 8 bits of the character).      */
  61.     for(i = 0;i < 8;i++)
  62.     {
  63.  
  64. /* Shift the high-order bit of the character into the low-order bit of the   */
  65. /* CRC, and shift the high-order bit of the CRC into bit 24.                 */
  66.         x = x << 1;                        /* Shift "x" left one bit */
  67.  
  68. /* Test to see if the old high-order bit of the CRC was a 1.                 */
  69.         if(x & 0x01000000)                     /* Test bit 24 of "x" */
  70.  
  71. /* If the old high-order bit of the CRC was a 1, exclusive-or it with a one  */
  72. /* to set it to 0, and exclusive-or the CRC with hex 1021 to produce the     */
  73. /* CCITT-recommended CRC generator of: X**16 + X**12 + X**5 + 1. To produce  */
  74. /* the CRC generator of: X**16 + X**15 + X**2 + 1, change the constant from  */
  75. /* 0x01102100 to 0x01800500. This will exclusive-or the CRC with hex 8005    */
  76. /* and produce the same CRC that IBM uses for their synchronous transmission */
  77. /* protocols.                                                                */
  78.             x = x ^ 0x01102100;     /* Exclusive-or "x" with a...*/
  79.                                               /* ...constant of hex 01102100 */
  80. /* And repeat 8 times.                                                       */
  81.     }                                               /* End of "for" loop */
  82.  
  83. /* Return the CRC as the 16 low-order bits of this function's value.         */
  84.     return(((x & 0x00ffff00) >> 8)); /* AND off the unneeded bits and... */
  85.                                   /* ...shift the result 8 bits to the right */
  86.  
  87. }
  88. /*
  89. *   crc_finish:
  90. *    This function must be called once after all the characters in a block
  91. *    have been processed for a message which is to be TRANSMITTED. It
  92. *    returns the calculated CRC bytes, which should be transmitted as the
  93. *    two characters following the block. The first of these 2 bytes
  94. *    must be taken from the high-order byte of the CRC, and the second
  95. *    must be taken from the low-order byte of the CRC. This routine is NOT
  96. *    called for a message which has been RECEIVED.
  97. *
  98. *   Calling sequence:
  99. *
  100. *    crc = crc_finish(crc);
  101. */
  102. short crc_finish(crc)
  103. short crc;
  104. {
  105. /* Call crc_update twice, passing it a character of hex 00 each time, to     */
  106. /* flush out the last 16 bits from the CRC calculation, and return the       */
  107. /* result as the value of this function.                                     */
  108.     return(crc_update(crc_update(crc,'\0'),'\0'));
  109.  
  110. }
  111.  
  112. /*
  113. * This is a sample of the use of the CRC functions, which calculates the
  114. * CRC for a 1-character message block, and then passes the resulting CRC back
  115. * into the CRC functions to see if the "received" 1-character message and CRC
  116. * are correct.
  117. */
  118. main()
  119. {
  120.  
  121.     short crc;                                     /* The calculated CRC */
  122.     char crc_char;                            /* The 1-character message */
  123.     char x, y;            /* 2 places to hold the 2 "received" CRC bytes */
  124.  
  125.     crc_char = 'A';                    /* Define the 1-character message */
  126.     crc = crc_clear();      /* Reset the CRC to "transmit" a new message */
  127.     crc = crc_update(crc,crc_char);   /* Update the CRC for the first... */
  128.                                    /* ...(and only) character of the message */
  129.     crc = crc_finish(crc);        /* Finish the transmission calculation */
  130.     x = (char)((crc & 0xff00) >> 8);  /* Extract the high-order CRC byte */
  131.     y = (char)(crc & 0x00ff);          /* And extract the low-order byte */
  132.     printf("%04x\n",crc);                           /* Print the results */
  133.  
  134.     crc = crc_clear();                 /* Prepare to "receive" a message */
  135.     crc = crc_update(crc,crc_char);   /* Update the CRC for the first... */
  136.                                    /* ...(and only) character of the message */
  137.     crc = crc_update(crc,x);     /* Pass both bytes of the "received"... */
  138.     crc = crc_update(crc,y);           /* ...CRC through crc_update, too */
  139.     printf("%04x\n",crc);    /* If the result was 0, then the message... */
  140.                                             /* ...was received without error */
  141.  
  142. }
  143.